// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

namespace SnapObjects.Data
{
    internal class SelectBuildStatement : SqlBuildStatement
    {
        private int _skip = -1;
        private int _take = -1;
        private bool _isDistinct = false;

        public SelectBuildStatement()
        {
            this.Select = new SqlBuildClause(this.OnChanged);
            this.From = new SqlBuildClause(this.OnChanged);
            this.Where = new SqlBuildClause(this.OnChanged);
            this.GroupBy = new SqlBuildClause(this.OnChanged);
            this.Having = new SqlBuildClause(this.OnChanged);
            this.OrderBy = new SqlBuildClause(this.OnChanged);
            this.Unions = new SqlBuildClause(this.OnChanged);
        }

        public SelectBuildStatement(bool ignoreDelimitIdentifier) : this()
        {
            this.IgnoreDelimitIdentifier = ignoreDelimitIdentifier;
        }

        public override SqlStatementType StatementType => SqlStatementType.Select;

        public int Skip
        {
            get => _skip;
            set
            {
                _skip = value;

                this.OnChanged(null);
            }
        }

        public int Take
        {
            get => _take;
            set
            {
                _take = value;

                this.OnChanged(null);
            }
        }

        public bool IsDistinct
        {
            get => _isDistinct;
            set
            {
                _isDistinct = value;

                this.OnChanged(null);
            }
        }

        public SqlBuildClause Select { get; private set; }

        public SqlBuildClause From { get; private set; }

        public SqlBuildClause Where { get; private set; }

        public SqlBuildClause GroupBy { get; private set; }

        public SqlBuildClause Having { get; private set; }

        public SqlBuildClause OrderBy { get; private set; }

        public SqlBuildClause Unions { get; private set; }

        internal bool IgnoreDelimitIdentifier { get; private set; }

        public override void Clear()
        {
            base.Clear();

            this.Select.Clear();
            this.From.Clear();
            this.Where.Clear();
            this.GroupBy.Clear();
            this.Having.Clear();
            this.OrderBy.Clear();
            this.Unions.Clear();
            _version = 0;
            this.Take = -1;
            this.Skip = -1;
        }
        public override SqlBuildStatement Clone()
        {
            var statement = new SelectBuildStatement()
            {
                Skip = this.Skip,
                Take = this.Take,
                IsDistinct = this.IsDistinct
            };

            statement.Select = this.Select.Clone(statement.OnChanged);
            statement.From = this.From.Clone(statement.OnChanged);
            statement.Where = this.Where.Clone(statement.OnChanged);
            statement.GroupBy = this.GroupBy.Clone(statement.OnChanged);
            statement.Having = this.Having.Clone(statement.OnChanged);
            statement.OrderBy = this.OrderBy.Clone(statement.OnChanged);
            statement.Unions = this.Unions.Clone(statement.OnChanged);
            statement.IgnoreDelimitIdentifier = this.IgnoreDelimitIdentifier;

            foreach (var p in this.Parameters)
            {
                statement.AddParameters(new SqlBuilderParameter(p.PlaceholdName, p.Name, p.DataType, p.Direction));
            }

            return statement;
        }
    }
}
